#include "pch.h"
#include "SpotLight.h"
#include "Rendering/DeferredConstantBuffers.h"

using namespace DirectX;

SpotLight::SpotLight(void) :
	LightBase(),
	m_lightPositionAndRange(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX),
	m_pointLightDetailsBuffer(),
	m_updateRequired(true)
{
}

void SpotLight::Initialize(ID3D11PixelShader* pixelShader, ID3D11Buffer* lightParametersBuffer, ID3D11Buffer* lightDetailsBuffer)
{
	LightBaseUpdateRequired();
	m_updateRequired = true;

	m_pixelShader = pixelShader;
	m_lightParametersBuffer = lightParametersBuffer;
	m_pointLightDetailsBuffer = lightDetailsBuffer;
}

void SpotLight::LightPosition(float x, float y, float z)
{
	auto w = m_lightPositionAndRange.w;
	m_lightPositionAndRange = XMFLOAT4(x, y, z, w);
	m_updateRequired = true;
}

DirectX::XMFLOAT3 SpotLight::LightPosition(void)
{
	return XMFLOAT3(m_lightPositionAndRange.x, m_lightPositionAndRange.y, m_lightPositionAndRange.z);
}

void SpotLight::LightRange(float range)
{
	m_lightPositionAndRange.w = range;
	m_updateRequired = true;
}

float SpotLight::LightRange(void)
{
	return m_lightPositionAndRange.w;
}

void SpotLight::Render(ID3D11DeviceContext* context, UINT indexCount, UINT startIndexLocation, UINT baseVertexLocation)
{
	LightBase::SetBuffersForRendering(context);

	if (m_updateRequired)
	{
		LightPassPointLightDetails details = {};
		details.LightPositionAndRange = m_lightPositionAndRange;
		context->UpdateSubresource(m_pointLightDetailsBuffer.Get(), 0, nullptr, &details, 0, 0);
		m_updateRequired = false;
	}
	context->PSSetConstantBuffers(3, 1, m_pointLightDetailsBuffer.GetAddressOf());
	context->PSSetShader(m_pixelShader.Get(), nullptr, 0);
	context->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
}

float SpotLight::GetDepthForSorting(const XMFLOAT4X4& viewMatrix)
{
	return m_lightPositionAndRange.z;
}
